﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;

namespace DAL
{
    public partial  class  Comparativo
    {

        public int idAudit { get; set; }


        


        public string getCorrelativo(dbGestionDataContext _db,int idObra)
        {
            string  numDocumento="";

            //int c = _db.Comparativo.Where(p=>p.idObra==idObra).Count();

            var q= from  a in _db.Comparativos
                   where a.idObra==idObra
                   group a by a.idObra into g
                   select  new
                   {
                       idObra=g.Key,
                       numDocumento=g.Max(p=>p.numDocumento)
                   };


             

            if (q.Count()==0)
            {
                numDocumento="000001";
            }
            else
            {
                int numActual = int.Parse(q.First().numDocumento);
                numActual++;

                
                if (numActual < 10)
                {
                    numDocumento = "00000" + numActual.ToString();
                }
                else if (numActual < 100)
                {
                    numDocumento = "0000" + numActual.ToString();
                }
                else if (numActual < 1000)
                {
                    numDocumento = "000" + numActual.ToString();
                }
                else if (numActual < 10000)
                {
                    numDocumento = "00" + numActual.ToString();
                }
                else if (numActual < 100000)
                {
                    numDocumento = "0" + numActual.ToString();
                }
                else if (numActual < 1000000)
                {
                    numDocumento = numActual.ToString();
                }
                else if (numActual > 1000000)
                {
                    throw new Exception("Limite  de Correlativo Comparativo");
                }


            }
            return numDocumento;

        }

//        public view_Comparativo loadViewFromEstructuraCosto
//            (dbGestionDataContext _db, int idEsturcturaCosto)
//        {

//            view_Comparativo comparativo= new view_Comparativo();

//            view_EstructuraCosto estructura= 
//                _db.view_EstructuraCosto.Single(p=>p.idInternal==idEsturcturaCosto);

            
//comparativo.idEstructuraCosto=idEsturcturaCosto;
//comparativo.descripcion=estructura.descripcion;
//comparativo.totalBase=estructura.monto;
//comparativo.idEstado=1;

//            return comparativo;
//        }


        //El comparativo  registrado inicial  con el monto base original
        //  no se considera como comparativo detalle
        public decimal getMontoBaseTotal(dbGestionDataContext _db)
        {
            decimal result = 0;
            // total comparado 

            var q = (from i in _db.ComparativoItems
                     where i.idComparativo == this.idInternal &
                     i.bitSel ==true
                     select i);
            if (q.Count() > 0)
            {
                result = q.Sum(p => p.totalBase).Value;
            }


            return Math.Round(result, 4);
        }
        public decimal getMontoComparativoTotal(dbGestionDataContext _db)
        {
            decimal result = 0;

            var q = (from i in _db.ComparativoItems
                     where i.idComparativo == this.idInternal &
                     i.bitSel == true
                     select i);
            if (q.Count() > 0)
            {
                result = q.Sum(p => p.totalBaseOrigen).Value;
            }


            return Math.Round(result, 4);
        }


        public decimal getMontoBaseAContratadoTotal(dbGestionDataContext _db)
        {
            decimal result = 0;
        
            

            var q = (from i in _db.ComparativoItems
                     where i.idComparativo == this.idInternal &
                     i.bitSel == true & i.ComparativoItemSelecPrvs.Count() > 0  &  i.cantUso>0 
                     select i);
            
            
            //para lo que resta  agregar
            if (q.Count() > 0)
            {
                // mostramos el base del comparativo del solo utilizado

                if (this.idProveedorSelec == null)
                {

                    result = q.Sum(p => (p.cantUso) * p.precioBase).Value;
                }
                

            }
            else
            {            // en caso de no ser  utilizo
                var qq = (from i in _db.ComparativoItems
                          where i.idComparativo == this.idInternal &
                          i.bitSel == true
                          select i);
                if (qq.Count() > 0)
                {
                    result = qq.Sum(p => (p.totalBase)).Value;
                }
            }
            return Math.Round(result, 2);
        }
        public decimal getMontoBasePorAprobarTotal(dbGestionDataContext _db)
        {
            decimal result = 0;

            var q = (from i in _db.ComparativoItems
                     where i.idComparativo == this.idInternal &
                     i.bitSel == true &
                     i.ComparativoItemSelecPrvs.Count() > 0 & (i.cantidadBase - i.cantUso)>0
                     select i);


            //para lo que resta  agregar
            if (q.Count() > 0)
            {
                // mostramos el base del comparativo del solo utilizado
                    //lo disponible 
                    result = q.Sum(p => (p.cantidadBase - p.cantUso) * p.precioBase).Value;
                
            }
           
            return Math.Round(result, 2);
        }

        public decimal getMontoBaseContrataListaTotal(dbGestionDataContext _db)
        {
            decimal result = 0;

            var q = (from i in _db.ComparativoItemSelecPrv
                     where i.ComparativoItem.idComparativo== this.idInternal  &
                     i.ComparativoItem.bitSel == true 
                     select i);


            //para lo que resta  agregar
            if (q.Count() > 0)
            {
                // mostramos el base del comparativo del solo utilizado
                //lo disponible 
                result = q.Sum(p => p.total).Value;

            }
            //else
            //{            // en caso de no ser  utilizo
            //    var qq = (from i in _db.ComparativoItem
            //              where i.idComparativo == this.idInternal &
            //              i.bitSel == true
            //              select i);
            //    if (qq.Count() > 0)
            //    {
            //        result = qq.Sum(p => (p.totalBase)).Value;
            //    }
            //}
            return Math.Round(result, 2);
        }
     

        public decimal getMontoContratadoTotal(dbGestionDataContext _db)
        {
            decimal result = 0;

            var q = from i in _db.ComparativoProveedors
                    where i.idComparativo == this.idInternal
                    select i;
            if (q.Count() > 0)
            {

                result = q.Sum(p => p.totalContratado).Value;
            }


            return result;
        }

        public decimal getMontoUsoTotal(dbGestionDataContext _db, int idComparativo)
        {
            decimal result = 0;

            var q = (from i in _db.ComparativoProveedors
                     where i.idComparativo == idComparativo
                     select i);
            if (q.Count() > 0)
            {
                result = q.Sum(p => p.totalUso).Value;
            }


            return result;
        }


       

        public int getidAnterior(dbGestionDataContext _db, int idinternal, int idObra)
        {
            int intAnterior = 0;


            var id = from i in _db.Comparativos
                     where i.idInternal < idinternal && i.idObra == idObra
                     group i by i.idObra into g
                     select new
                     {
                         idAnterior = g.Max(p => p.idInternal)
                     };

            if (id.Count() > 0)
            {
                intAnterior = id.First().idAnterior;

            }
            else
            {
                throw new Exception("No existe Registros");
            }


            return intAnterior;

        }

        public int getidSiguiente(dbGestionDataContext _db, int idinternal, int idObra)
        {
            int intSiguiente = 0;

            //revisar la sentencia generada
            var id = from i in _db.Comparativos
                     where i.idInternal > idinternal && i.idObra == idObra
                     group i by i.idObra into g
                     select new
                     {
                         idSiguiente = g.Min(p => p.idInternal)
                     };


            if (id.Count() > 0)
            {
                intSiguiente = id.First().idSiguiente;

            }
            else
            {
                throw new Exception("No existe Registros");
            }

            return intSiguiente;
        }

        public bool add(dbGestionDataContext _db,
                        int  idEstructuraCosto,
                        DateTime fecha,
                        string descripcion,
                        decimal tipoCambio,
                        string Observaciones,
                         int idProveedorSeleccion,
                        int idObra,
                        int idMoneda,
                        int idUsuario)
                {
            this.idEstructuraCosto=idEstructuraCosto;
            this.fechaCreacion=DateTime.Now;
            this.fecha=fecha;
            this.descripcion=descripcion;
            this.tipoCambio=tipoCambio;
            this.totalBase=0;
            this.totalComparativo = 0;
            this.Observaciones=Observaciones;
            this.idObra=idObra;
            this.numDocumento = this.getCorrelativo(_db, idObra); 
            this.idEstado=1; //emison
            this.usuarioCre=idUsuario;
            this.fechacre=DateTime.Now;
            this.usuarioMod=idUsuario;
            this.fechaMod=DateTime.Now;
            this.idMoneda=idMoneda;
            this.idProveedorSelec = idProveedorSeleccion;
            _db.Comparativos.InsertOnSubmit(this);

           _db.SubmitChanges();
            // auditoria antes de guardar

            AuditRecord auditRecord = new AuditRecord();
            this.idAudit = auditRecord.add(_db,
            DAL.AuditAction.Insert,
            idUsuario,
            this.idInternal,
            this);
   


         
            return true;
            }

        public bool update(dbGestionDataContext _db,
                                DateTime fecha,
                               string descripcion,
                                int idMoneda,
                                decimal tipoCambio,
                                string observacion,
                                int idEmpleadoEdit)
        {
            this.fecha = fecha;
            //this.idgrupo = idEstructura;
            this.descripcion = descripcion;
            //this.idMoneda 
            this.idMoneda= idMoneda;
            this.tipoCambio = tipoCambio;
            this.Observaciones = observacion;
            this.fechaMod = DateTime.Now;
            this.usuarioMod = idEmpleadoEdit;

            // auditoria antes de guardar

            AuditRecord auditRecord = new AuditRecord();
            this.idAudit=auditRecord.add(_db,
                DAL.AuditAction.Update,
                idEmpleadoEdit,
                this.idInternal,
                this);
   

            _db.SubmitChanges();
            return true;
        }

        public void updateProveedorSelec(dbGestionDataContext _db,int idProveedor)
        {
            
            this.idProveedorSelec = idProveedor;
            _db.SubmitChanges();
        }


        public void  updateTotalComparativo(dbGestionDataContext _db)
        {
            this.totalComparativo = this.getMontoComparativoTotal(_db);
             this.totalBase = this.getMontoBaseTotal(_db);

                 // auditoria antes de guardar

                 //AuditRecord auditRecord = _db.AuditRecord.Single(p => p.Id == this.idAudit);
                 //auditRecord.update(_db,this,AuditAction.Update);
   
            _db.SubmitChanges();

           
            
         }



        public void updateDesAprobacion(dbGestionDataContext _db, int idEmpleadoDesApr)
        {


            this.idEstado = 1; // Generado

            this.fechaAprob = null;
            this.fechaRevisor = null;
            this.fechaMod = DateTime.Now;
            
            this.idEmpleadoAprob = null;
            this.idEmpleadoRevisor = null;

            var q = from a in _db.OrdenCompras
                    where a.idComparativo == this.idInternal
                    select a;

            //if (q.Count() == 0)
            //{
            //        this.idProveedorSelec = null;
            //}
            


            // auditoria antes de guardar

            AuditRecord auditRecord = new AuditRecord();
            this.idAudit = auditRecord.add(_db,
                DAL.AuditAction.Update,
                idEmpleadoDesApr,
                this.idInternal,
                this);
            
            _db.SubmitChanges();
        }


         
        
        
        public void UpdateAprobacion(dbGestionDataContext _db, int idEmpleadoAprob)
        {



            this.idEstado = 3; // aprobado
            this.fechaAprob = DateTime.Now;
            this.idEmpleadoAprob = idEmpleadoAprob;

            // actualizamos la aprobacion
            // auditoria antes de guardar

            AuditRecord auditRecord = new AuditRecord();
            this.idAudit = auditRecord.add(_db,
                DAL.AuditAction.Update,
                idEmpleadoAprob,
                this.idInternal,
                this);

            _db.SubmitChanges();
        }


        public void UpdateRevisor(dbGestionDataContext _db, int idEmpleadoRevisor)
        {


            this.idEstado = 2; // aprobado 1
            this.fechaRevisor = DateTime.Now;
            this.idEmpleadoRevisor = idEmpleadoRevisor;

            // actualizamos la aprobacion 1
            // auditoria antes de guardar

            AuditRecord auditRecord = new AuditRecord();
            this.idAudit = auditRecord.add(_db,
                DAL.AuditAction.Update,
                idEmpleadoRevisor,
                this.idInternal,
                this);

            _db.SubmitChanges();
        }


        public bool updateUsoFromOrdenCompra(dbGestionDataContext _db)
        {

            Obra obra = _db.Obras.Single(p => p.idInternal == this.idObra);
            
            var q = from a in _db.ComparativoItemSelecPrv
                    where a.ComparativoItem.idComparativo == this.idInternal
                    select a;


            // actualizamos sus comparativositemSelec

            foreach (var a in q)
            {

                a.updateUso(_db, obra.incluyeIGV.Value);
            }

            var qq = from a in _db.ComparativoItems
                     where a.idComparativo == this.idInternal
                     select a;


            //actualizo el uso del item
            foreach (var b in qq)
            {
                b.updateTotalesUso(_db);
            }


            var qqq = from a in _db.ComparativoProveedors
                     where a.idComparativo == this.idInternal
                     select a;

            foreach (var c in qqq)
            {
                c.updateMontoUso(_db);
            }

            return true;
        }



        //private void verificaSaldoComparativo()
        //{
        //    //mejorar la presicion
        //    decimal totaf = Math.Abs((this.ComparativoItemSelecPrv.total.Value - this.ComparativoItemSelecPrv.totalUso.Value));
        //    decimal cantidadf = Math.Abs((this.ComparativoItemSelecPrv.cantidad.Value - this.ComparativoItemSelecPrv.cantidadUso.Value));

        //    if (totaf > 0.01m)
        //    {
        //        throw new Exception("No puede ingresar Montos Superiores");
        //    }


        //    if (cantidadf > 0.01m)
        //    {
        //        throw new Exception("No puede ingresar cantidades Superiores");
        //    }


        //}
    }
}
